package ui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

/**
 * An AutoSuggest TextField that uses a ComboBox to 
 * attempt to predict user input based on a list 
 * that is defined at construction and updated with
 * each keystroke. The TextField only includes exact
 * matches.
 * 
 *
 */
public class AutoSuggest extends JPanel {
	public final JTextField textField;
	private final JComboBox comboBox = new JComboBox();
	private final Vector<String> vector = new Vector<String>();
	private boolean hide = false;
	
	/**
	 * Constructor for the AutoSuggest TextField. The elements
	 * included in the Suggestion Box are specified in the ArrayList
	 * of elements
	 * @param elements The elements to be included in the suggestion box.
	 */
	public AutoSuggest(ArrayList<String> elements) {
		super(new BorderLayout());
		for (String s : elements) {
			vector.add(s);
		}
		comboBox.setEditable(true);
		textField = (JTextField) comboBox.getEditor().getEditorComponent();
		textField.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						
						String text = textField.getText();
						
						if (text.length() == 0) {
							comboBox.hidePopup();
							setModel(new DefaultComboBoxModel(vector), "");
						} else {
							DefaultComboBoxModel comboBoxModel = getSuggestedModel(vector,text);
							if (comboBoxModel.getSize() == 0 || hide) {
								comboBox.hidePopup();
								hide = false;
							} else {
								setModel(comboBoxModel, text);
								comboBox.showPopup();
							}
						}
					}
				});
			}

			public void keyPressed(KeyEvent e) {
				String text = textField.getText();
				int code = e.getKeyCode();
				if (code == KeyEvent.VK_ENTER) {
					if (!vector.contains(text)) {
						vector.addElement(text);
						Collections.sort(vector);
						setModel(getSuggestedModel(vector, text), text);
						}
					hide = true;
				} else if (code == KeyEvent.VK_ESCAPE) {
					hide = true;
				} else if (code == KeyEvent.VK_RIGHT) {
					for (int i = 0; i < vector.size(); i++) {
						String str = vector.elementAt(i);
						if (str.toLowerCase().startsWith(text.toLowerCase())) {
							comboBox.setSelectedIndex(-1);
							textField.setText(str);
							return;
						}
					}
				}
			}
		});
		setModel(new DefaultComboBoxModel(vector), "");
		JPanel p = new JPanel(new BorderLayout());
		p.add(comboBox, BorderLayout.NORTH);
		add(p);
		setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		setPreferredSize(new Dimension(200, 40));
	}
	
	
	private void setModel(DefaultComboBoxModel comboBoxModel, String str) {
		comboBox.setModel(comboBoxModel);
		comboBox.setSelectedIndex(-1);
		textField.setText(str);
	}

	private static DefaultComboBoxModel getSuggestedModel(
			java.util.List<String> list, String text) {
		DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
		comboBoxModel.getSize();
		for (String s : list) {
			if (s.toLowerCase().startsWith(text.toLowerCase()))
				comboBoxModel.addElement(s);
		}
		return comboBoxModel;
	}

}

